<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/css/all.min.css" integrity="sha256-mUZM63G8m73Mcidfrv5E+Y61y7a12O5mW4ezU3bxqW4=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"tallgy.gitee.io","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":false,"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"}}</script><script src="/js/config.js"></script>
<meta name="description" content="只是一个知识的搬运工">
<meta property="og:type" content="website">
<meta property="og:title" content="tallgy&#39;s blog">
<meta property="og:url" content="http://tallgy.gitee.io/page/7/index.html">
<meta property="og:site_name" content="tallgy&#39;s blog">
<meta property="og:description" content="只是一个知识的搬运工">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="tallgy">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="http://tallgy.gitee.io/page/7/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":true,"isPost":false,"lang":"zh-CN","comments":"","permalink":"","path":"page/7/index.html","title":""}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>tallgy's blog</title>
  




  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">tallgy's blog</h1>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>







</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-overview-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">tallgy</p>
  <div class="site-description" itemprop="description">只是一个知识的搬运工</div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">107</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">32</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">74</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner index posts-expand">

    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/10/JavaScript/JavaScript%E5%8F%98%E9%87%8F%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/10/JavaScript/JavaScript%E5%8F%98%E9%87%8F%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F/" class="post-title-link" itemprop="url">JavaScript变量的作用域</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-10 20:18:30" itemprop="dateCreated datePublished" datetime="2021-11-10T20:18:30+08:00">2021-11-10</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/" itemprop="url" rel="index"><span itemprop="name">JavaScript</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/%E9%9A%8F%E7%AC%94/" itemprop="url" rel="index"><span itemprop="name">随笔</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="JavaScript变量的作用域-Scpoe"><a href="#JavaScript变量的作用域-Scpoe" class="headerlink" title="JavaScript变量的作用域 Scpoe"></a>JavaScript变量的作用域 Scpoe</h1><p>​        作用域的概念，简单来说就是对于一个 a = 1，这个操作等于了在全局变量上进行了创建。如同使用一个普通函数 fn()，一样，这个函数的this指向也是全局的变量。</p>
<ul>
<li><p>浏览器和node的一个小区别，在全局变量中，</p>
<ul>
<li><p>node的全局变量，是一个名为Global 的全局对象，并且使用 var定义的变量不会加入其中，只有直接定义的变量会加入其中。</p>
<ul>
<li>```<br>var a = 1;<br>b = 2;<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* 浏览器的全局变量，是一个window对象，使用var定义的变量和直接定义的变量也会加入其中。</span><br><span class="line"></span><br><span class="line">  * ```</span><br><span class="line">    a = 1;</span><br><span class="line">    var b = 2;</span><br><span class="line">    </span><br><span class="line">    下面定义的不会加入其中。</span><br><span class="line">    let c = 3;</span><br><span class="line">    const d = 4;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
</li>
</ul>
<p>这里的一个问题，就是你会发现，这里的a为什么是先输出的1.</p>
<p>​        开始我的理解是，先有个a的参数嘛，然后又预定义了一个a，因为这个var是在词法环境的阶段进行了操作。然后再进行了输出，此时就应该是undefined，但是是不对的。</p>
<p>​        <strong>个人认为正确的理解</strong>：首先我们得知道var的定义是在词法环境的创建的时候进行的定义，所以我们就知道了函数的参数其实是在词法环境之后进行的赋值，所以我们是先定义了一个 var a; 此时这个a为undefined，然后便是进行一个参数a的赋值，此时这个a以及被定义了，所以a的赋值是在a的定义之后的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">(function (a) &#123;</span><br><span class="line">  console.log(a);</span><br><span class="line">  var a = 4;</span><br><span class="line">  console.log(a);</span><br><span class="line">&#125;)(1)</span><br><span class="line"></span><br><span class="line">1</span><br><span class="line">4</span><br></pre></td></tr></table></figure>


      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/10/JavaScript/ES6/JavaScript%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/10/JavaScript/ES6/JavaScript%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0/" class="post-title-link" itemprop="url">JavaScript箭头函数</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-10 19:42:56" itemprop="dateCreated datePublished" datetime="2021-11-10T19:42:56+08:00">2021-11-10</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/" itemprop="url" rel="index"><span itemprop="name">JavaScript</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/%E9%9A%8F%E7%AC%94/" itemprop="url" rel="index"><span itemprop="name">随笔</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="JavaScript箭头函数"><a href="#JavaScript箭头函数" class="headerlink" title="JavaScript箭头函数"></a>JavaScript箭头函数</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions</span><br></pre></td></tr></table></figure>



<p>​        <strong>箭头函数表达式</strong>的语法比<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/function">函数表达式</a>更简洁，并且没有自己的<code>this</code>，<code>arguments</code>，<code>super</code>或<code>new.target</code>。箭头函数表达式更适用于那些本来需要匿名函数的地方，并且它不能用作构造函数。</p>
<h2 id="特点"><a href="#特点" class="headerlink" title="特点"></a>特点</h2><ul>
<li>没有自己的this，它只会从自己的作用域链的上一层继承this。</li>
<li>没有arguments，不能使用自己的arguments对象。使用的arguments都是自己作用域的arguments。</li>
<li>不能用做构造函数，代表了不能使用new方法。使用了new方法会抛出异常。</li>
<li>与严格模式的关系，除了this指向以外，其他规则不变</li>
<li>通过call方法和apply进行调用的this指向被忽略</li>
<li>没有prototype属性</li>
<li>不能使用yield关键字，不能用作函数生成器</li>
<li>参数和箭头不能换行</li>
<li>箭头函数具有与常规函数不同的特殊<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">运算符优先级</a>解析规则。 <strong>call || () =&gt; {}</strong> 会先执行call || () 然后再执行 =&gt; {}，所以要在后面使用(), 进行分割。</li>
</ul>
<h2 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">let fn = (args) =&gt; &#123;</span><br><span class="line">  xxxx</span><br><span class="line">  return ;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​        对于单个参数的可以简写，()</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">v =&gt; &#123;&#125;</span><br></pre></td></tr></table></figure>

<p>​        对于只有一条return 语句的，{}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">() =&gt; xxx;</span><br></pre></td></tr></table></figure>



<p><strong>高级语法</strong>：</p>
<p>​        因为这里首先只有一个直接的return 语句，所以可以省略了{}，然后返回的是对象，所以添加了{}，导致的问题就是不知道这个括号所代表的含义，所以使用了()，来进行区分。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">//加括号的函数体返回对象字面量表达式：</span><br><span class="line">params =&gt; (&#123;foo: bar&#125;)</span><br></pre></td></tr></table></figure>

<p>​        剩余参数，简单来说就是一个es6的一个赋值方式 …args，后面的参数都会放入这个数组</p>
<p>​        默认参数，就是不带参数和带的undefined的参数 param=defaultValue</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">//支持剩余参数和默认参数</span><br><span class="line">(param1, param2, ...rest) =&gt; &#123; statements &#125;</span><br><span class="line">(param1 = defaultValue1, param2, …, paramN = defaultValueN) =&gt; &#123;</span><br><span class="line">statements &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>​        就是es6的解构方法。详细的解构方法，我们可以后续在填。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">//同样支持参数列表解构</span><br><span class="line">let f = ([a, b] = [1, 2], &#123;x: c&#125; = &#123;x: a + b&#125;) =&gt; a + b + c;</span><br><span class="line">f();  // 6</span><br></pre></td></tr></table></figure>



<h2 id="this指向"><a href="#this指向" class="headerlink" title="this指向"></a>this指向</h2><p>​        箭头函数的一个特点就是this指向的固定，这里我们可以知道箭头函数的this指向是定义时词法作用域的指向。</p>
<p>​        这里可能就有一个思考了，为什么这个会和定义时的词法作用域相关。而不是和使用时的作用域相关。我们也许就该这样思考了，<strong>也许</strong>说明在定义阶段，如果有使用了this的方法，会进行一个提前的指向。</p>
<p>​        箭头函数不会创建自己的<code>this,它只会从自己的作用域链的上一层继承this</code> 函数，语法块等都有自己的作用域链{} </p>
<p>​        作用域链，其实就是箭头函数this指向的是一个词法环境，词法环境在es6中的定义已经和作用域链相差无几。对象是不生成词法环境，但是注意普通函数可以将对象也作为一个this的指向。</p>
<p>​        <strong>这里有个小知识点</strong>：</p>
<ul>
<li>就是node端和浏览器端，对于var的定义不同：<ul>
<li>node不会将var定义的变量加入全局。</li>
<li>浏览器端会将var定义的变量加入全局。</li>
</ul>
</li>
</ul>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/09/JavaScript/%E5%AF%B9%E8%B1%A1/JavaScript%E5%8E%9F%E5%9E%8B%E9%93%BE/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/09/JavaScript/%E5%AF%B9%E8%B1%A1/JavaScript%E5%8E%9F%E5%9E%8B%E9%93%BE/" class="post-title-link" itemprop="url">JavaScript原型链</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-09 20:57:32" itemprop="dateCreated datePublished" datetime="2021-11-09T20:57:32+08:00">2021-11-09</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/" itemprop="url" rel="index"><span itemprop="name">JavaScript</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/%E9%9A%8F%E7%AC%94/" itemprop="url" rel="index"><span itemprop="name">随笔</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="JavaScript原型链"><a href="#JavaScript原型链" class="headerlink" title="JavaScript原型链"></a>JavaScript原型链</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">原型链，就像是Java中的继承一样，可以让子类取访问父类的属性，可以将一些公用的东西写在原型上。</span><br><span class="line">是一个 __proto__ 的不断指向上一层。</span><br><span class="line"></span><br><span class="line">同时箭头函数没有 prototype ，所以不能使用new方法</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>先看一张图，简单来说</p>
<p>​        原型其实就是一个方法的实例，然后每一个方法的实例有一个__proto__ 的指向。这个指向会直到指到null为止。这样所生产的就是一个原型链，对于在本层找不到的方法，会通过原型链逐层向上查找。</p>
<p>​        一个方法是和一个原型对应的，而一个原型又是一个另一个方法的实例，所以这里的对应关系在于，一个方法的实例默认是没有constructor构造函数，此时这个实例就是一个单纯的底层实例，但是如果我们将一个构造函数的原型指向了这个实例，并且将这个实例的构造器指向了原型， 那么这个实例就已经算是一个原型了，此时就已经不是一个单纯的底层实例了。</p>
<p>​        顶层的方法就是 Function，顶层的原型就是Object.prototype，而Object方法确实使用了Function的原型。</p>
<img src="/.io//290701352241158.jpg" alt="290701352241158" style="zoom:67%;">



<h1 id="JavaScript-继承"><a href="#JavaScript-继承" class="headerlink" title="JavaScript 继承"></a>JavaScript 继承</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">function Fn() &#123;</span><br><span class="line">  this.name = 1;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">let a = new Fn();</span><br><span class="line"></span><br><span class="line">此时的</span><br><span class="line">a.__proto__ = Fn.prototype</span><br><span class="line">a.__proto__.constructor = Fn;</span><br></pre></td></tr></table></figure>

<h2 id="new-方法的行为"><a href="#new-方法的行为" class="headerlink" title="new 方法的行为"></a>new 方法的行为</h2><p>​        我们要这样思考，这个new方法。</p>
<ul>
<li>new 一个方法，会创建的一个this的指向。</li>
<li>然后会执行这个方法，执行结束之后。</li>
<li>创建一个 __proto__  指向了 方法的 prototype 的指向。</li>
<li>然后就进行返回。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">let _this = &#123;&#125;;</span><br><span class="line">let result = Fn.apply(_this, args);</span><br><span class="line">_this.__proto__ = Fn.prototype;</span><br><span class="line">return typeof result === &#x27;object&#x27; ? result : __this__;</span><br></pre></td></tr></table></figure>

<p>​        同时这里，在进行 new 方法的调用时，我们知道，如果返回的是一个引用类型，那么便会直接返回这个引用类型，如果返回的是一个值类型，那么返回的便是自己所创建的this指向。我们可以知道一个引用类型，无论你是使用的new方法，还是直接进行的创建的引用类型。其结果都会创建原型。</p>
<p><strong>注意</strong>：</p>
<p>​        对于一个值类型，进行了new 方法，也会变成引用类型的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">let x = new Number(1);</span><br><span class="line">let y = new Number(1);</span><br><span class="line"></span><br><span class="line">console.log(x === y); //false</span><br></pre></td></tr></table></figure>



<h2 id="JavaScript-继承："><a href="#JavaScript-继承：" class="headerlink" title="JavaScript 继承："></a><strong>JavaScript 继承</strong>：</h2><h3 id="继承的思路"><a href="#继承的思路" class="headerlink" title="继承的思路"></a>继承的思路</h3><p>继承，简单的理解就是，子类的实例可以访问父类的方法</p>
<p>同时我们可以知道，父类的方法，创建的实例才能进行调用。</p>
<p>而父类的prototype，已经可以算作为父类的父类的方法了。</p>
<p>所以，我们在不考虑上级的方法之前，需要将父类的方法进行传递，</p>
<p>这里，可以考虑使用一个新的对象进行指定。如果我一个新对象</p>
<h3 id="原型和构造器"><a href="#原型和构造器" class="headerlink" title="原型和构造器"></a>原型和构造器</h3><p>这里和Java的一个不同点</p>
<p>我印象中，Java是子类有多个，父类越来越少的一种情况，</p>
<img src="/.io//image-20211110100356010.png" alt="image-20211110100356010" style="zoom:67%;">

<p>​        一开始，我是这样思考的，构造函数和实例是对应的，而构造函数的原型应该是属于上层的一个实例了。</p>
<p>​        但是你仔细观察，发现，一个构造函数的原型是和构造函数进行了对应。思想应该是每个实例都有一个原型，但是其原型默认是没有constructor的（这里可以使用 hasOwnProperty 进行证明）。我们所使用的constructor属性其实都是我们的实例的原型  __proto__ 中的constructor，但是实例的原型为什么会带有constructor，这里我的认为是，一个函数默认在词法编译阶段，会默认指向一个prototype，而这个行为就是 </p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Fn.protorype = new Object();</span><br><span class="line">Fn.prototype.constructor = Fn;</span><br></pre></td></tr></table></figure>

<p>​    简单来说，就是在没有指定的情况下，默认先创建一个顶级的对象实例，里面只有最原始的方法，然后再对这个实例创建一个本函数的构造行为。</p>
<img src="/.io//image-20211110101346723.png" alt="image-20211110101346723" style="zoom:67%;">

<p>​        而这个JavaScript是每个子类，都会将父类进行一次实例的操作，所以造成了每个父类的实例和子类的构造函数一一对应了。</p>
<h3 id="new-方法实现"><a href="#new-方法实现" class="headerlink" title="new 方法实现"></a>new 方法实现</h3><h4 id="new-关键字会进行如下的操作："><a href="#new-关键字会进行如下的操作：" class="headerlink" title="new 关键字会进行如下的操作："></a><strong><code>new</code> 关键字会进行如下的操作：</strong></h4><ol>
<li>创建一个空的简单JavaScript对象（即<code>&#123;&#125;</code>）；</li>
<li>为步骤1新创建的对象添加属性**<strong>proto</strong>**，将该属性链接至构造函数的原型对象 ；</li>
<li>将步骤1新创建的对象作为<code>this</code>的上下文 ；</li>
<li>如果该函数没有返回对象，则返回<code>this</code>。</li>
</ol>
<h4 id="当代码-new-Foo-执行时，会发生以下事情："><a href="#当代码-new-Foo-执行时，会发生以下事情：" class="headerlink" title="当代码 new Foo(...) 执行时，会发生以下事情："></a><strong>当代码 <code>new Foo(...)</code> 执行时，会发生以下事情：</strong></h4><ol>
<li>一个继承自 <code>Foo.prototype</code> 的新对象被创建。</li>
<li>使用指定的参数调用构造函数 <em><code>Foo</code><em>，并将 <code>this</code> 绑定到新创建的对象。<code>new Foo</code> 等同于 <em><code>new Foo</code></em><code>()</code>，也就是没有指定参数列表，</em><code>Foo</code></em> 不带任何参数调用的情况。</li>
<li>由构造函数返回的对象就是 <code>new</code> 表达式的结果。如果构造函数没有显式返回一个对象，则使用步骤1创建的对象。（一般情况下，构造函数不返回值，但是用户可以选择主动返回对象，来覆盖正常的对象创建步骤）</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">function create(Fn, ...args) &#123;</span><br><span class="line">  let _this = &#123;&#125;;</span><br><span class="line">  let result = Fn.apply(_this, args);</span><br><span class="line">  _this.__proto__ = Fn.prototype;</span><br><span class="line">  return typeof result === &#x27;object&#x27; ? result : _this;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="继承的方式"><a href="#继承的方式" class="headerlink" title="继承的方式"></a>继承的方式</h3><h4 id="原型链继承"><a href="#原型链继承" class="headerlink" title="原型链继承"></a>原型链继承</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Children.prototype = new Father();</span><br><span class="line">Children.prototype.constructor = Children;</span><br></pre></td></tr></table></figure>

<p>​        很简单的理解，就是直接将子类的原型修改为了父类的实例，然后再对实例的constructor进行一个校准，修改为子类的构造。</p>
<p>​        执行new方法的行为的步骤：</p>
<ul>
<li>产生一个this指向，__proto__  的添加，指向为children.prototype。就是 Father的实例。</li>
<li>执行children的构造函数，this指向的调用。</li>
<li>返回。</li>
</ul>
<p><strong>缺点</strong>：</p>
<ul>
<li>对于要在原型上添加修改的方法，需要在 new Father 之后，因为这个是直接将一个地址进行了转换。</li>
<li>其次就是不会将参数传递到父类。只适合不带参数的。</li>
<li>因为实例是在直接对原型的创建，所以，所有的实例都是共有的。当然，因为这个创建本就无法带参数，共有实例其实并没有什么问题。</li>
</ul>
<h4 id="组合继承"><a href="#组合继承" class="headerlink" title="组合继承"></a>组合继承</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">function Children() &#123;</span><br><span class="line">	Father.call(this);</span><br><span class="line">&#125;</span><br><span class="line">Children.prototype = new Father();</span><br><span class="line">Children.prototype.constructor = Children;</span><br></pre></td></tr></table></figure>

<p>​        这个和原型链继承大同小异，就是多了一个在构造函数内部使用call方法调用父类。使用call方法调用时是不会产生 __proto__  和 constructor 的。但是你可能会发现自己测试还是有啊，但是你仔细观察，其实你自己测试所生成的 __proto__  和 constructor 是在创建对象的时候生成的。所以，其实并没有真正的生成。</p>
<p><strong>缺点</strong>：</p>
<ul>
<li>new 方法 和 call 方法都生成了一份实例。</li>
</ul>
<h4 id="寄生组合继承"><a href="#寄生组合继承" class="headerlink" title="寄生组合继承"></a>寄生组合继承</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">function Children() &#123;</span><br><span class="line">	Father.call(this);</span><br><span class="line">&#125;</span><br><span class="line">(function () &#123;</span><br><span class="line">	let Super = function() &#123;&#125;;</span><br><span class="line">	Super.prototype = Father.prototype;</span><br><span class="line">	Children.prototype = new Super();</span><br><span class="line">	Children.prototype.constructor = Children;</span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure>

<p>​        我们可以查看这个和 组合继承的区别，使用了一个空方法将Father的原型复制了过来，所以new所生成的方法就只生成了一个空对象，和一个原型。Father的方法实则已经在call方法里面进行了调用。</p>
<h5 id="寄生组合继承的思考"><a href="#寄生组合继承的思考" class="headerlink" title="寄生组合继承的思考"></a>寄生组合继承的思考</h5><p>为什么我们会这样使用寄生组合继承</p>
<p>我们可以从各个方面进行思考，</p>
<p>首先继承无非就是子类想要使用上父类的元素，然后这里就需要调用父类的方法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">function Children() &#123;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br><span class="line">Children.prototype = new Father();</span><br><span class="line"></span><br><span class="line">这个方法的问题是无法传参。</span><br><span class="line">这里修改了原型指向，所以需要进行构造函数的指向转变</span><br><span class="line">Children.prototype.constructor = Children;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">function Children() &#123;</span><br><span class="line">	let instance = new Father(xxx);</span><br><span class="line">	</span><br><span class="line">	return instance;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">这个方法是可以传递参数了，但是这个方法就不是父类的实例了，因为是在子类被创建，所以我们要不就是对子类也同用这个instance对象进行操作。但是这样有点不符合一种规范</span><br><span class="line">这里是使用了instance方式，而instance实则是父类的实例，所以如果需要进行子类实例的操作。需要在new Fahter的后面，然后将this转换成instance，然后对于proto和构造 函数都是父函数的。很有问题的感觉</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">function Children() &#123;</span><br><span class="line">	Father.call(this);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">在这里，我是将父元素的方法进行了执行，当然，如果是对于父元素返回的是一个对象的，那么将会是一个不同的操作，但是在正常的情况下，通过这个可以获取到父元素的构造函数执行方法，但是，问题在于没有原型指向的改变。所以我们需要进行原型指向的改变。</span><br><span class="line">简单来说，这里已经获取到了父函数的实例对象，只需要将原型指向进行改变即可</span><br><span class="line">Children.prototype = new Father();</span><br><span class="line">Children.prototype.constructor = Children;</span><br><span class="line">通过上面这个方法，我们获取到了原型的指向，修改为了父元素的实例。唯一的问题就是进行了两次Father的使用，可以考虑对于父函数的实例进行一个处理</span><br><span class="line"></span><br><span class="line">let Super = funtion() &#123;&#125;;</span><br><span class="line">Super.prototype = Father.prototype;</span><br><span class="line">Children.prototype = new Super();</span><br><span class="line">Children.prototype.constructor = Children;</span><br><span class="line">区别，new的是Super，Super里面没有实例，所以里面只有一个原型的指向。</span><br><span class="line">而Super的原型的指向已经被修改为了Father的原型。</span><br><span class="line">此时我们只需要在对构造函数进行一个修改即可。</span><br></pre></td></tr></table></figure>



<p>所以最后我们使用了寄生组合继承，方式就是在内部使用call方法调用了父函数，获取了父函数的实例方法，然后在外部创建一个空函数，原型指向了父函数的原型，然后再对其实例赋值给了子类的原型，此时因为空函数的实例内部是没有的，所以其实内部的共有属性就只有proto，和 constructor。然后在修改原型的构造。</p>
<p>​        所以整的来说，这个方式，只生成了相同的父类的实例的方法，并且放在了子类的实例中，所以不会出现共有属性，其次就是原型是在外部进行的实现，所以原型又是共有的。其次就是对原型的构造函数进行了指向。</p>
<p>​        所以很完美。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/07/Node%20JS/JavaScript%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/07/Node%20JS/JavaScript%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF/" class="post-title-link" itemprop="url">JavaScript事件循环</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-07 20:23:56" itemprop="dateCreated datePublished" datetime="2021-11-07T20:23:56+08:00">2021-11-07</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/" itemprop="url" rel="index"><span itemprop="name">JavaScript</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/%E9%9A%8F%E7%AC%94/" itemprop="url" rel="index"><span itemprop="name">随笔</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="JavaScript的事件循环机制"><a href="#JavaScript的事件循环机制" class="headerlink" title="JavaScript的事件循环机制"></a>JavaScript的事件循环机制</h1><p>这里分为 NodeJS 和 浏览器环境</p>
<p>​    因为 Node JS虽然是使用了 浏览器的V8处理器 作为一个JavaScript的解释器，但是其中的IO处理实则还是使用的 libuv 引擎。</p>
<h2 id="浏览器的事件循环"><a href="#浏览器的事件循环" class="headerlink" title="浏览器的事件循环"></a>浏览器的事件循环</h2><p>​        这里先引入一个概念，叫做**任务队列(Task Queue)**，简单来说就是维护了一个需要执行的函数的一个队列。</p>
<p>​        在这里，任务队列又分为了**宏任务队列(macro task)<strong>和</strong>微任务队列(micro task)**。</p>
<p>​        简单来说就是JavaScript，在执行的过程中，如果遇到了异步处理，就会将其推入任务队列。然后继续执行后面的函数。直到执行结束，然后才会调用任务队列的任务进行执行。</p>
<p>​        这里是先调用的 微任务队列的方法，先执行，直至微任务队列为空，这里如果产生了微任务，也会即刻放入这个微任务队列中，因为这是一个的队列。微任务队列执行结束，然后就会从宏任务队列中取出一个来进行执行，方式就如同上面那样，这样即产生了事件的循环。</p>
<p>​        <strong>常见宏任务</strong>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">script (可以理解为外层同步代码)、setTimeout/setInterval、setImmediate(Node.js)、I/O、UI事件、postMessage。</span><br></pre></td></tr></table></figure>

<p>​        因为在这里，我们如果将最外层的同步代码视为第一个宏任务队列的话，我们就可以这样理解，先取出一个宏任务，然后再执行，然后再执行微任务，然后又取出宏任务这样循环。</p>
<p>​        <strong>常见微任务</strong>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Promise.then、process.nextTick(Node.js) 这里nextTick会先于微任务执行、Object.observe、MutaionObserver。</span><br></pre></td></tr></table></figure>

<p>​        这里 Promise里面算是一个同步的代码，只是then方法是一个异步的。所以then方法算是一个微任务。</p>
<h2 id="Node-JS的事件循环"><a href="#Node-JS的事件循环" class="headerlink" title="Node JS的事件循环"></a>Node JS的事件循环</h2><p> <strong>官方文档</strong>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttick/</span><br></pre></td></tr></table></figure>

<p>事件循环操作顺序的简化图</p>
<img src="/.io//image-20211107211640084.png" alt="image-20211107211640084" style="zoom:80%;">

<p>一个框，便为事件循环的一个阶段</p>
<p>​        每个阶段都有一个FIFO(first input first output，就是队列) 队列，通常情况下，当进入给定的阶段，将执行该阶段的行为。然后执行回调，直到队列用尽或者最大回调数的执行。然后事件循环将移动到下一阶段。</p>
<p>​        由于这些操作中的任何一个都可能调度 <em>更多的</em> 操作和由内核排列在<strong>轮询</strong>阶段被处理的新事件， 且在处理轮询中的事件时，轮询事件可以排队。因此，长时间运行的回调可以允许轮询阶段运行长于计时器的阈值时间。有关详细信息，请参阅 <a target="_blank" rel="noopener" href="https://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttick/#timers"><strong>计时器</strong></a> 和 <a target="_blank" rel="noopener" href="https://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttick/#poll"><strong>轮询</strong></a> 部分。<strong>（没看懂，直接复制的原文，后续再解读）</strong></p>
<h3 id="阶段概述："><a href="#阶段概述：" class="headerlink" title="阶段概述："></a><strong>阶段概述</strong>：</h3><ul>
<li>定时器（timers）： 本阶段执行已经被 <code>setTimeout()</code> 和 <code>setInterval()</code> 的调度回调函数。</li>
<li>待定回调（pending callbacks）：执行延迟到下一个循环迭代的I/O回调</li>
<li>idle，prepare：仅系统内部使用</li>
<li>轮询（poll）：检索新的I/O事件；执行与I/O相关的回调（几乎所有情况下，除了关闭的回调函数，那些由计时器和<code>setImmediate</code>调度的之外），其余情况node将在适当的时候在此阻塞</li>
<li>检测（check）：<code>setImmediate()</code> 回调函数在这里执行。</li>
<li>关闭的回调函数（close callbacks）：一些关闭的回调函数，如：<code>socket.on(&#39;close&#39;, ...)</code>。</li>
</ul>
<p>在每次运行的事件循环之间，Node JS检查它是否在等待任何异步I/O或者计时器，如果没有，则完全关闭。</p>
<h3 id="阶段的详细概述"><a href="#阶段的详细概述" class="headerlink" title="阶段的详细概述"></a>阶段的详细概述</h3><h4 id="定时器"><a href="#定时器" class="headerlink" title="定时器"></a>定时器</h4><p>​        可以执行所提供回调的阈值，而不是执行的确切事件，是指在时间间隔后，回调将尽快的执行。但是，操作系统或其他正在运行的回调可能会延迟它们的执行。</p>
<h4 id="待定回调"><a href="#待定回调" class="headerlink" title="待定回调"></a>待定回调</h4><p>​        对某些系统操作（如 TCP 错误类型）执行回调。例如，如果 TCP 套接字在尝试连接时接收到 <code>ECONNREFUSED</code>，则某些 *nix 的系统希望等待报告错误。</p>
<h4 id="轮询"><a href="#轮询" class="headerlink" title="轮询"></a>轮询</h4><p>两个重要的功能：</p>
<ul>
<li>计算应该 阻塞和轮询I/O的时间。</li>
<li>处理轮询队列里的事件。</li>
</ul>
<p>当事件循环进入轮询阶段，且没有被调度的计时器时，将发生以下两种情况：</p>
<ul>
<li>如果轮询队列不是空的，事件循环将循环访问回调队列并同步执行它们，直到队列已用尽，或者达到了与系统相关的硬性限制。<ul>
<li>为了防止轮询阶段饿死事件循环，<a target="_blank" rel="noopener" href="https://libuv.org/">libuv</a>（实现 Node.js 事件循环和平台的所有异步行为的 C 函数库），在停止轮询以获得更多事件之前，还有一个硬性最大值（依赖于系统）。</li>
</ul>
</li>
<li><em>如果 <strong>轮询</strong> 队列 <strong>是空的</strong></em> ，还有两件事发生：<ul>
<li>如果脚本被 <code>setImmediate()</code> 调度，则事件循环将结束 <strong>轮询</strong> 阶段，并继续 <strong>检查</strong> 阶段以执行那些被调度的脚本。</li>
<li>如果脚本 <strong>未被</strong> <code>setImmediate()</code>调度，则事件循环将等待回调被添加到队列中，然后立即执行。</li>
</ul>
</li>
</ul>
<p>一旦 <strong>轮询</strong> 队列为空，事件循环将检查 _已达到时间阈值的计时器_。如果一个或多个计时器已准备就绪，则事件循环将绕回计时器阶段以执行这些计时器的回调。</p>
<h4 id="检查阶段"><a href="#检查阶段" class="headerlink" title="检查阶段"></a>检查阶段</h4><p>​        此阶段允许人员在轮询阶段完成后立即执行回调。如果轮询阶段变为空闲状态，并且脚本使用 <code>setImmediate()</code> 后被排列在队列中，则事件循环可能继续到 <strong>检查</strong> 阶段而不是等待。</p>
<p>​        <code>setImmediate()</code> 实际上是一个在事件循环的单独阶段运行的特殊计时器。它使用一个 libuv API 来安排回调在 <strong>轮询</strong> 阶段完成后执行。</p>
<h4 id="关闭的回调函数"><a href="#关闭的回调函数" class="headerlink" title="关闭的回调函数"></a>关闭的回调函数</h4><p>​        如果套接字或处理函数突然关闭（例如 <code>socket.destroy()</code>），则<code>&#39;close&#39;</code> 事件将在这个阶段发出。否则它将通过 <code>process.nextTick()</code> 发出。</p>
<p>​        任何时候在给定的阶段中调用 <code>process.nextTick()</code>，所有传递到 <code>process.nextTick()</code> 的回调将在事件循环继续之前解析。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/07/Vue/VueRouter%E4%B8%A4%E7%A7%8D%E6%A8%A1%E5%BC%8F/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/07/Vue/VueRouter%E4%B8%A4%E7%A7%8D%E6%A8%A1%E5%BC%8F/" class="post-title-link" itemprop="url">VueRouter两种模式</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-07 13:33:21" itemprop="dateCreated datePublished" datetime="2021-11-07T13:33:21+08:00">2021-11-07</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Vue/" itemprop="url" rel="index"><span itemprop="name">Vue</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Vue/VueRouter/" itemprop="url" rel="index"><span itemprop="name">VueRouter</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="VueRouter的两种模式"><a href="#VueRouter的两种模式" class="headerlink" title="VueRouter的两种模式"></a>VueRouter的两种模式</h1><p>有history 和 hash两个模式</p>
<h2 id="history模式"><a href="#history模式" class="headerlink" title="history模式"></a>history模式</h2><p>在这里我先直接说一下history模式的问题，简单来说就是不能刷新页面，因为后端没有对其进行一个处理。</p>
<p>这里开始我想了很久都没有理解是什么意思，并且在本地访问也没有任何问题，后面才知道，这个是需要发布的时候，正式访问才会出现的问题。</p>
<p>首先，history模式在本地是没有问题的，只有在打包之后，运行那个dist文件夹服务才会发现</p>
<p>其次，问题的复现很简单，</p>
<ul>
<li>先运行<strong>打包</strong>之后的项目，然后访问，注意，一定要打包之后的，如果直接运行server，你不会发现这个问题。</li>
<li>此时一般都是 <code>http://localhost:3000</code> 这种，访问之后，url一般都会根据前端的路由进行一次变化 <code>http://localhost:3000/bookkeeping</code> 我这里就变成这样了。</li>
<li>然后此时如果你刷新，请求的就是 <code>http://localhost:3000/bookkeeping</code> 而不是最开始那个，如果你没有对这个进行一个处理，那么就会404.</li>
</ul>
<p>解决方法，简单来说就是对没有的域名都进行一个跳转为index.html页面的情况。</p>
<ul>
<li> <strong>方式1</strong>：</li>
</ul>
<p>  这个方式的前提条件就是 前端和后端的项目是合并的。并不是一个分离式的开发。此时的话，我们也可以知道，前端的页面请求是先通过了后端，然后后端进行配置，对于一些没有的路径进行一个处理即可</p>
<ul>
<li> <strong>方式2</strong>：</li>
</ul>
<p>  前后端进行了分离，这个时候就对前端运行就好了。下面这个是Vue的一个例子，我们在dist文件里新建一个js文件作为一个启动文件。然后在这里进行了一个文件的拦截，就像是一种虽然前后端分离，但是实则还是有一个后端。</p>
  <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">const http = require(&#x27;http&#x27;)</span><br><span class="line">const fs = require(&#x27;fs&#x27;)</span><br><span class="line">const httpPort = 80</span><br><span class="line"></span><br><span class="line">http.createServer((req, res) =&gt; &#123;</span><br><span class="line">  fs.readFile(&#x27;index.html&#x27;, &#x27;utf-8&#x27;, (err, content) =&gt; &#123;</span><br><span class="line">    if (err) &#123;</span><br><span class="line">      console.log(&#x27;We cannot open &quot;index.html&quot; file.&#x27;)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    res.writeHead(200, &#123;</span><br><span class="line">      &#x27;Content-Type&#x27;: &#x27;text/html; charset=utf-8&#x27;</span><br><span class="line">    &#125;)</span><br><span class="line"></span><br><span class="line">    res.end(content)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;).listen(httpPort, () =&gt; &#123;</span><br><span class="line">  console.log(&#x27;Server listening on: http://localhost:%s&#x27;, httpPort)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<ul>
<li> <strong>方式3</strong>：</li>
</ul>
<p>  使用nginx进行代理。这里我没有成功，不知道是哪的问题，大致好像是使用 rewired进行重定向操作。具体以后再说。</p>
<h2 id="hash模式"><a href="#hash模式" class="headerlink" title="hash模式"></a>hash模式</h2><p>​        hash模式，简单来说就是使用的 url的#，因为url的#是不会参与请求，所以基本没有什么问题，除了不怎么好看之外。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/07/JavaScript/ES6/async%E5%92%8Cawait%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/07/JavaScript/ES6/async%E5%92%8Cawait%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/" class="post-title-link" itemprop="url">async和await的基本使用</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-07 10:34:28" itemprop="dateCreated datePublished" datetime="2021-11-07T10:34:28+08:00">2021-11-07</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/" itemprop="url" rel="index"><span itemprop="name">JavaScript</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JavaScript/Promise/" itemprop="url" rel="index"><span itemprop="name">Promise</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="async和await"><a href="#async和await" class="headerlink" title="async和await"></a>async和await</h1><p>​        简单来说就像是将一个异步转化为一个同步的操作。</p>
<p>​        简单的使用方式</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">async function name() &#123;</span><br><span class="line">	await xxx;</span><br><span class="line">	</span><br><span class="line">	return 3;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​        首先，await需要在 async之内，否则会报错，其次await等待的是一个promise对象，否则就没有什么效果。</p>
<p><strong>上面的函数的执行：</strong></p>
<ul>
<li>先执行了async函数，创建了一个Promise，此时为pending阶段</li>
<li>然后进入函数内部，执行到了await部分。如果await后面接一个promise的行为，等待一个resolve的返回，async函数内部后面的一些方法不会执行，但是不会影响到外面的函数的继续 运行。</li>
<li>接收到了resolve，将其值返回。</li>
<li>然后继续运行，直到结束或return，有return x，则为resolve(x); 如果是返回一个promise方法，则获取其resolve或者reject进行执行。</li>
</ul>
<p>​        先看看示例</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">async function test() &#123;</span><br><span class="line"></span><br><span class="line">  let a = await new Promise((resolve, reject) =&gt; &#123;</span><br><span class="line">    setTimeout(() =&gt; &#123;</span><br><span class="line">      resolve(1);</span><br><span class="line">    &#125;, 2000);</span><br><span class="line">  &#125;)</span><br><span class="line">  console.log(a);</span><br><span class="line"></span><br><span class="line">  return 3;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">test().then((res) =&gt; console.log(res));</span><br><span class="line">console.log(111);</span><br></pre></td></tr></table></figure>

<p>​        我们分析一下：</p>
<ul>
<li>首先，可以知道a=1，test的resolve为3。</li>
<li>然后就是执行的顺序了，</li>
<li>async函数执行，发现是一个promise的方法，直接先执行后续函数。然后再执行promise，这个是调度的机制</li>
<li>async函数内部执行，虽然a后面是一个promise方法，但是使用了await，所以后面的会等待。</li>
<li>输出a，执行后面的，return 3</li>
<li>return 3，就类似于了Promise.resolve(3)，所以test.then 可以调用。</li>
</ul>
<h2 id="reject处理"><a href="#reject处理" class="headerlink" title="reject处理"></a>reject处理</h2><p>​        我们同时也可以发现，如果在 async函数内部调用了reject，会直接抛出异常。</p>
<p>​        此时我们的处理方式，一般来说趋向于使用try，catch进行错误捕获，然后对错误进行处理。</p>
<p>对于错误的处理也有两种方式：</p>
<ul>
<li>```<br>async function test() {  let a = await new Promise((resolve, reject) =&gt; {<pre><code>setTimeout(() =&gt; &#123;
  reject(1);
&#125;, 100);
</code></pre>
  }).catch(e =&gt; console.log(‘err’));<br>  console.log(a);  return 123;<br>}test()<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">* ```</span><br><span class="line">    try &#123;</span><br><span class="line">      a = await new Promise((resolve, reject) =&gt; &#123;</span><br><span class="line">        setTimeout(() =&gt; &#123;</span><br><span class="line">          reject(1);</span><br><span class="line">        &#125;, 100);</span><br><span class="line">      &#125;);</span><br><span class="line">      console.log(a);</span><br><span class="line">    &#125; catch (e) &#123;</span><br><span class="line">      console.log(e + &#x27; -- &#x27;);</span><br><span class="line">      console.log(&#x27;err&#x27;);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">  输出：</span><br><span class="line">  1 --</span><br><span class="line">  err</span><br><span class="line">  </span><br></pre></td></tr></table></figure></li>
</ul>
<p>注意点：</p>
<p>​    这里catch的e，是reject传递的值。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/06/%E9%9A%8F%E7%AC%94/RESTful/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/06/%E9%9A%8F%E7%AC%94/RESTful/" class="post-title-link" itemprop="url">RESTful</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-06 15:24:20" itemprop="dateCreated datePublished" datetime="2021-11-06T15:24:20+08:00">2021-11-06</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E9%9A%8F%E7%AC%94/" itemprop="url" rel="index"><span itemprop="name">随笔</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="RESTful架构"><a href="#RESTful架构" class="headerlink" title="RESTful架构"></a>RESTful架构</h1><p>REST：<strong>Representational State Transfer</strong> 的简写</p>
<p>就是表现层状态转化</p>
<p>简单理解：</p>
<ul>
<li>url 表示的是一个资源，就是一个实体，一个具体的信息</li>
<li>而操作作为一个HTTP请求路径和方法来进行一个体现。</li>
<li>常用的方法操作：<ul>
<li>GET：获取资源</li>
<li>POST：新建或更新资源</li>
<li>PUT：更新资源</li>
<li>DELETE：删除资源</li>
</ul>
</li>
<li>客户端通过HTTP的方法和路径，实现对服务器端资源进行操作。</li>
</ul>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/06/JavaScript/%E9%9A%8F%E7%AC%94/WebWorker/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/06/JavaScript/%E9%9A%8F%E7%AC%94/WebWorker/" class="post-title-link" itemprop="url">WebWorker</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-06 14:49:25" itemprop="dateCreated datePublished" datetime="2021-11-06T14:49:25+08:00">2021-11-06</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E9%9A%8F%E7%AC%94/" itemprop="url" rel="index"><span itemprop="name">随笔</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="WebWorker"><a href="#WebWorker" class="headerlink" title="WebWorker"></a>WebWorker</h1><p>参考文章</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">http://www.ruanyifeng.com/blog/2018/07/web-worker.html</span><br><span class="line">https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API</span><br></pre></td></tr></table></figure>



<h2 id="是什么"><a href="#是什么" class="headerlink" title="是什么"></a>是什么</h2><p>​        简单来说就是为JavaScript提供了多线程。一些计算密集型或高延迟的任务，被 Worker 线程负担了，主线程（通常负责 UI 交互）就会很流畅，不会被阻塞或拖慢。</p>
<p><strong>注意点</strong>：</p>
<ul>
<li>同源的限制</li>
<li>无法使用DOM对象，document，window，parent对象，可以使用navigator 和 location 对象。</li>
<li>和主线程通过消息进行通信</li>
<li>不能使用 alert 和 confirm 方法，但是可以使用 XMLHttpRequest 对象发出 AJAX 请求。</li>
<li>无法读取本地文件。</li>
</ul>
<p><strong>用法</strong>：</p>
<p>使用 new 调用 worker 函数，创建一个线程</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">const worker = new Worker(&#x27;xx.js&#x27;);</span><br></pre></td></tr></table></figure>

<p>​        参数是一个脚本文件，这个文件必须来自网络</p>
<h3 id="主线程："><a href="#主线程：" class="headerlink" title="主线程："></a>主线程：</h3><p>主线程通过 worker.postMessage() 向Worker发送消息</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">worker.postMessage(&#x27;Hello World&#x27;);</span><br><span class="line">worker.postMessage(&#123;method: &#x27;echo&#x27;, args: [&#x27;Work&#x27;]&#125;);</span><br></pre></td></tr></table></figure>

<p>​        参数就是传给worker的数据</p>
<p>主线程通过 worker.onmessage 监听函数，接收子线程发回的消息</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">worker.onmessage = function (event) &#123;</span><br><span class="line">	event.data.log;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​        事件对象的data属性可以获取 worker发来的数据</p>
<p>主线程关闭worker线程</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">worker.terminate();</span><br></pre></td></tr></table></figure>



<h3 id="Worker线程"><a href="#Worker线程" class="headerlink" title="Worker线程"></a>Worker线程</h3><p>worker线程需要一个监听函数，监听 message 事件</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">self.addEventListener(&#x27;message&#x27;, function(e) &#123;</span><br><span class="line">	self.postMessage(&#x27;said: &#x27;, e.data);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>​        <code>self</code>代表子线程自身，即子线程的全局对象</p>
<p>所以等同于 this. 和 直接创建</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">this.addEventListener();</span><br><span class="line">addEventListener();</span><br></pre></td></tr></table></figure>

<p>​        也可以使用 self.onmessage 指定</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">self.onmessage = function (e) &#123;</span><br><span class="line">	self.postMessage(&#x27;said: &#x27;, e.data);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>​        监听函数的参数是一个事件对象，data属性是主线程发来的数据</p>
<p>self.postMessage() 方法用来向主线程发送消息</p>
<p>self.close() 用于在Worker内部关闭自身。</p>
<h1 id="API"><a href="#API" class="headerlink" title="API"></a>API</h1><h2 id="创建API"><a href="#创建API" class="headerlink" title="创建API"></a>创建API</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">const worker = new Worker(jsUrl, options);</span><br><span class="line"></span><br><span class="line">var myWorker = new Worker(&#x27;worker.js&#x27;, &#123; name : &#x27;myWorker&#x27; &#125;);</span><br></pre></td></tr></table></figure>

<p>​        jsUrl,脚本网址,遵守同源策略，必须且是js脚本</p>
<p>​        options是一个配置对象，其中一个作用就是指定worker名称用来区分线程。</p>
<h2 id="主线程使用API"><a href="#主线程使用API" class="headerlink" title="主线程使用API"></a>主线程使用API</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">Worker.onerror</span><br><span class="line">	指定 error 事件的监听函数。</span><br><span class="line">Worker.onmessage</span><br><span class="line">	指定 message 事件的监听函数，发送过来的数据在Event.data属性中。</span><br><span class="line">Worker.onmessageerror</span><br><span class="line">	指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时，会触发这个事件。</span><br><span class="line">Worker.postMessage()</span><br><span class="line">	向 Worker 线程发送消息。</span><br><span class="line">Worker.terminate()</span><br><span class="line">	立即终止 Worker 线程。</span><br></pre></td></tr></table></figure>



<h2 id="Worker线程使用API"><a href="#Worker线程使用API" class="headerlink" title="Worker线程使用API"></a>Worker线程使用API</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">self.name</span><br><span class="line">	Worker 的名字。该属性只读，由构造函数指定。</span><br><span class="line">self.onmessage</span><br><span class="line">	指定message事件的监听函数。</span><br><span class="line">self.onmessageerror</span><br><span class="line">	指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时，会触发这个事件。</span><br><span class="line">self.close()</span><br><span class="line">	关闭 Worker 线程。</span><br><span class="line">self.postMessage()</span><br><span class="line">	向产生这个 Worker 线程发送消息。</span><br><span class="line">self.importScripts()</span><br><span class="line">	加载 JS 脚本。</span><br></pre></td></tr></table></figure>


      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/06/%E6%B5%8F%E8%A7%88%E5%99%A8/Cookie%E3%80%81SessionStorage%E3%80%81LocalStorage%E7%9A%84%E5%8C%BA%E5%88%AB/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/06/%E6%B5%8F%E8%A7%88%E5%99%A8/Cookie%E3%80%81SessionStorage%E3%80%81LocalStorage%E7%9A%84%E5%8C%BA%E5%88%AB/" class="post-title-link" itemprop="url">Cookie、SessionStorage、LocalStorage的区别</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-06 13:35:43" itemprop="dateCreated datePublished" datetime="2021-11-06T13:35:43+08:00">2021-11-06</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E9%9A%8F%E7%AC%94/" itemprop="url" rel="index"><span itemprop="name">随笔</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="Cookie、SessionStorage、LocalStorage的区别"><a href="#Cookie、SessionStorage、LocalStorage的区别" class="headerlink" title="Cookie、SessionStorage、LocalStorage的区别"></a>Cookie、SessionStorage、LocalStorage的区别</h1><p><strong>共同点：</strong></p>
<ul>
<li>保存于浏览器端</li>
<li>属于同源</li>
</ul>
<h2 id="Cookie"><a href="#Cookie" class="headerlink" title="Cookie"></a>Cookie</h2><ul>
<li>数据始终在同源的HTTP请求中携带，即使不需要。</li>
<li>存在路径的概念，可以限制cookie只属于某个路径。</li>
<li>存储的大小只有4k左右。</li>
<li>一般由服务器生成，设置过期时间，如果不设置过期时间，则表示这个cookie生命周期为浏览器会话期间，只要关闭浏览器窗口，cookie就消失了。</li>
</ul>
<p>使用：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">JavaScript</span><br><span class="line">	document.cookie = &#x27;key=value&#x27;;</span><br><span class="line">	</span><br><span class="line">HTTP响应头的 set-cookie</span><br></pre></td></tr></table></figure>



<h3 id="安全机制"><a href="#安全机制" class="headerlink" title="安全机制"></a>安全机制</h3><ul>
<li>响应头中setCookie设置HttpOnly 使JavaScript无法进行获取。</li>
<li>响应头设置 secure，告诉浏览器仅在HTTPS请求发送cookie</li>
<li>人为的设置时间，以及对key和value进行一些随机的生成。</li>
</ul>
<h2 id="SessionStorage"><a href="#SessionStorage" class="headerlink" title="SessionStorage"></a>SessionStorage</h2><ul>
<li>存储时间：浏览器窗口关闭前有效，就是一个标签页。在标签页中，进行刷新也不会消失，但是关闭就会消失。</li>
<li>即使是同域名下的页面，只要不在同一浏览器窗口打开，那么他们的SessionStorage无法共享。</li>
<li>大小限制 5M</li>
<li>不和服务器进行通信，仅客户端使用</li>
</ul>
<p><strong>使用</strong>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sessionStorage.setItem(key, value);</span><br><span class="line">sessionStorage.getItem(key);</span><br></pre></td></tr></table></figure>



<h2 id="LocalStorage"><a href="#LocalStorage" class="headerlink" title="LocalStorage"></a>LocalStorage</h2><ul>
<li>存储时间：永久有效。用作持久数据</li>
<li>同源的页面可以访问，不同于SessionStorage。</li>
<li>其他基本和SessionStorage相同。</li>
<li>基于上面的特点，LocalStorage可以作为浏览器的本地缓存方案，用来提升网页首屏渲染速度（根据第一请求返回时，将一些不变的信息直接存储在本地）</li>
</ul>
<p><strong>使用</strong>：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">localStorage.setItem(key, value);</span><br><span class="line">localStorage.getItem(key);</span><br></pre></td></tr></table></figure>


      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://tallgy.gitee.io/2021/11/06/%E9%9A%8F%E7%AC%94/fetch%E5%8F%91%E9%80%812%E6%AC%A1%E8%AF%B7%E6%B1%82%E7%9A%84%E5%8E%9F%E5%9B%A0/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="tallgy">
      <meta itemprop="description" content="只是一个知识的搬运工">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="tallgy's blog">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/11/06/%E9%9A%8F%E7%AC%94/fetch%E5%8F%91%E9%80%812%E6%AC%A1%E8%AF%B7%E6%B1%82%E7%9A%84%E5%8E%9F%E5%9B%A0/" class="post-title-link" itemprop="url">fetch发送2次请求的原因</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-11-06 13:20:43" itemprop="dateCreated datePublished" datetime="2021-11-06T13:20:43+08:00">2021-11-06</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2023-06-25 16:57:29" itemprop="dateModified" datetime="2023-06-25T16:57:29+08:00">2023-06-25</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E9%9A%8F%E7%AC%94/" itemprop="url" rel="index"><span itemprop="name">随笔</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="fetch发送2次请求的原因"><a href="#fetch发送2次请求的原因" class="headerlink" title="fetch发送2次请求的原因"></a>fetch发送2次请求的原因</h1><p>fetch发送post请求的时候，总是发送2次，第一次状态码是204，第二次才成功？</p>
<p>原因很简单，因为你用fetch的post请求的时候，导致fetch 第一次发送了一个Options请求，询问服务器是否支持修改的请求头，如果服务器支持，则在第二次中发送真正的请求。</p>
<h2 id="先说产生的前提条件"><a href="#先说产生的前提条件" class="headerlink" title="先说产生的前提条件"></a>先说产生的前提条件</h2><ul>
<li>请求不同源</li>
<li>不属于简单请求</li>
</ul>
<h2 id="请求不同源"><a href="#请求不同源" class="headerlink" title="请求不同源"></a>请求不同源</h2><p>同源的概念：</p>
<p>​        如果两个 URL 的 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Glossary/Protocol">protocol</a>、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Glossary/Port">port (en-US)</a> (如果有指定的话)和 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Glossary/Host">host</a> 都相同的话，则这两个 URL 是<em>同源</em>。这个方案也被称为“协议/主机/端口元组”，或者直接是 “元组”。</p>
<p>所以简单来说，因为浏览器的安全策略，所以对于不同源的请求是不会成功的。</p>
<h2 id="不属于简单请求"><a href="#不属于简单请求" class="headerlink" title="不属于简单请求"></a>不属于简单请求</h2><p>简单请求：</p>
<ul>
<li>请求方法是以下三个方法：<ul>
<li>HEAD, GET, POST</li>
</ul>
</li>
<li>HTTP的头信息不超出以下几种字段<ul>
<li>Accept， Accept-Language， Content-Language， Last-Event-ID， Content-Type(只限于三个值<code>application/x-www-form-urlencoded</code>、<code>multipart/form-data</code>、<code>text/plain</code>)</li>
</ul>
</li>
</ul>
<p>不满足以上两个条件就属于非简单请求</p>
<h2 id="对于非简单请求，需要先进行预检请求-preflight"><a href="#对于非简单请求，需要先进行预检请求-preflight" class="headerlink" title="对于非简单请求，需要先进行预检请求(preflight)"></a>对于非简单请求，需要先进行预检请求(preflight)</h2><p>​        浏览器先询问服务器，当前网页所在的域名是否在服务器的许可名单之中，以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复，浏览器才会发出正式的<code>XMLHttpRequest</code>请求，否则就报错。</p>
<p>​        204的状态表示了处理了请求，没有返回实体内容。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/page/6/"><i class="fa fa-angle-left" aria-label="上一页"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/6/">6</a><span class="page-number current">7</span><a class="page-number" href="/page/8/">8</a><span class="space">&hellip;</span><a class="page-number" href="/page/11/">11</a><a class="extend next" rel="next" href="/page/8/"><i class="fa fa-angle-right" aria-label="下一页"></i></a>
  </nav>

</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2023</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">tallgy</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  





  





</body>
</html>
